package pikasial.images.traitements;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

public class RotateTraitement implements Traitement {

    protected BufferedImage source;
    protected int angle;

    public RotateTraitement(BufferedImage src, int angle) {
        setAngle(angle);
        source = src;
    }

    public void setAngle(int angle) {
        this.angle = angle % 360;
    }

    public int getAngle() {
        return angle;
    }

    public BufferedImage executeTraitement() {
        int w = source.getWidth();
        int h = source.getHeight();
        /* On utilise la diagonale pour redimensionner l'image avant la rotation afin
         * d'éviter de perdre des pixels. Les nouveaux pixels sont noirs
         */
        int diag = (int) Math.sqrt(h*h+w*w);
        int type = (source.getType() != BufferedImage.TYPE_CUSTOM)?source.getType():BufferedImage.TYPE_INT_ARGB;
        BufferedImage bImage = new BufferedImage(diag,diag,type);
        for (int i = 0; i < diag; i++) {
        	for (int j = 0; j < diag; j++) {
        		bImage.setRGB(i, j, 0x00000000);
        	}
        }
        Graphics2D g2 = bImage.createGraphics();
        g2.drawImage(source, (diag-w)/2, (diag-h)/2, null);

        /* Rotation */
        AffineTransform transform = new AffineTransform();
        transform.rotate((Math.toRadians(angle)),(diag/2),(diag/2));
        AffineTransformOp op = new AffineTransformOp(transform,
            AffineTransformOp.TYPE_BILINEAR);
        bImage = op.filter(bImage, null);

        BufferedImage bImage2;
        int nw = 0,nh = 0;
        if (angle % 90 == 0) {
        	if ((angle/90) % 2 == 0) { nw = w; nh = h; }
        	else { nw = h; nh = w; }
    		bImage2 = bImage.getSubimage((diag-nw)/2,(diag-nh)/2, nw, nh);
        } else {
        	bImage2 = bImage;
        }
        return bImage2;
    }

	public BufferedImage undoChanges() {
		return source;
	}
}
